<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>19.矩阵3d</title>
	<style>
		canvas {
            background-color: rebeccapurple;
		}
	</style>
	<script src="../utils/index.js"></script>
	<link rel="stylesheet" href="../utils/ui.css">
</head>
<body>
	<div id="ui">
		<div class="x"></div>
		<div class="y"></div>
		<div class="z"></div>
		<div class="scaleX"></div>
		<div class="scaleY"></div>
		<div class="scaleZ"></div>
		<div class="rotateX"></div>
		<div class="rotateY"></div>
		<div class="rotateZ"></div>
	</div>
	<canvas id="gl" style="background-color: rebeccapurple;"></canvas>
	<script type="x-shader/x-vertex" id="vertex">
		uniform mat4 u_matrix;
		attribute vec4 a_position;
		attribute vec4 a_color;
	    varying vec4 v_color;
		void main(){
			gl_Position = u_matrix*a_position;
			v_color=a_color;

		}
	</script>
	
	<script type="x-shader/x-fragment" id="fragment">
		precision mediump float;

	    varying vec4 v_color;
		void main(){
			gl_FragColor =v_color;
		}
	</script>
	
	<script>
		 /** @type {HTMLCanvasElement} */   
		const canvas=document.getElementById("gl")
		const gl=canvas.getContext("webgl")
		canvas.width=1000
		canvas.height=1000
		//流程 1.创建着色器 编译 链接
		const vertex=document.getElementById("vertex").textContent
		const fragment=document.getElementById("fragment").textContent
		
		const vertexShader=gl.createShader(gl.VERTEX_SHADER)
		const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
		gl.shaderSource(vertexShader,vertex)
		gl.shaderSource(fragmentShader,fragment)
		gl.compileShader(vertexShader)
		gl.compileShader(fragmentShader)
		const program=gl.createProgram()
		gl.attachShader(program,vertexShader)
		gl.attachShader(program,fragmentShader)
		gl.linkProgram(program)
		gl.useProgram(program)
		gl.viewport(0,0,1000,1000)


		const u_matrix=gl.getUniformLocation(program,"u_matrix")
		let m4=webglUtils.Mat4
		let matrix=m4.create()
		gl.uniformMatrix4fv(u_matrix,false,matrix)

		
		const translation=[500,500,0]
		const scale=[1,1,1]
		let rotate=[45,45,0]
		const centre=[-100,-100,-100]//中心点
		{
			
			webglUtils.setupSlider(".x",{
				min:0,
				max:1000,
				value:translation[0],
				step:1,
				handle:(e,v)=>{
					translation[0]=v.value
				}
			})
			webglUtils.setupSlider(".y",{
				min:0,
				max:1000,
				value:translation[1],
				step:1,
				handle:(e,v)=>{
					translation[1]=v.value
				}
			})
			webglUtils.setupSlider(".z",{
				min:-1000,
				max:1000,
				value:translation[2],
				step:1,
				handle:(e,v)=>{
					translation[2]=v.value
				}
			})
			webglUtils.setupSlider(".scaleX",{
				min:-10,
				max:10,
				value:1,
				step:1,
				handle:(e,v)=>{
					scale[0]=v.value
				}
			})
			webglUtils.setupSlider(".scaleY",{
				min:-10,
				max:10,
				value:1,
				step:1,
				handle:(e,v)=>{
					scale[1]=v.value
				}
			})
			webglUtils.setupSlider(".scaleZ",{
				min:-10,
				max:10,
				value:1,
				step:1,
				handle:(e,v)=>{
					scale[2]=v.value
				}
			})
			webglUtils.setupSlider(".rotateX",{
				min:0,
				max:360,
				value:0,
				step:1,
				handle:(e,v)=>{
					rotate[0]=v.value
				}
			})
			webglUtils.setupSlider(".rotateY",{
				min:0,
				max:360,
				value:0,
				step:1,
				handle:(e,v)=>{
					rotate[1]=v.value
				}
			})
			webglUtils.setupSlider(".rotateZ",{
				min:0,
				max:360,
				value:0,
				step:1,
				handle:(e,v)=>{
					rotate[2]=v.value
				}
			})
		}
		const a_position=gl.getAttribLocation(program,"a_position")
		const a_color=gl.getAttribLocation(program,"a_color")
		/*
				h1		h4
			q1	 q4
				h2		h3
			q2	 q3

		
		*/
		const q1=[-100,100,100],q2=[-100,-100,100],q3=[100,-100,100],q4=[100,100,100],h1=[-100,100,-100],h2=[-100,-100,-100],h3=[100,-100,-100],h4=[100,100,-100]
		const pos=[
			...q1,...q2,...q3,...q3,...q4,...q1,//前
			...h3,...h2,...h1,...h1,...h4,...h3,//后

			...h2,...q2,...q1,...h2,...q1,...h1,//左
			...q4,...q3,...h3,...h3,...h4,...q4,//右

			...q1,...q4,...h4,...h4,...h1,...q1,//上
			...h3,...q3,...q2,...q2,...h2,...h3,//下
			
		]
		function randomColor(){
			return [Math.floor(Math.random()*255),Math.floor(Math.random()*255),Math.floor(Math.random()*255)]
		}
		const colors=[]
		for (let index = 0; index < 6; index++) {
			let a=randomColor()
			colors.push(
				...a,...a,...a,
				...a,...a,...a
			)
		}

		let r=0
		function draw(t){
			const bufferData=gl.createBuffer()
			gl.bindBuffer(gl.ARRAY_BUFFER,bufferData)
			gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pos), gl.STATIC_DRAW)
			gl.enableVertexAttribArray(a_position)
			gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, 0, 0)

			const colorB=gl.createBuffer()
			gl.bindBuffer(gl.ARRAY_BUFFER, colorB)
			gl.bufferData(gl.ARRAY_BUFFER,new Uint8Array(colors),gl.STATIC_DRAW)
			gl.enableVertexAttribArray(a_color)
			gl.vertexAttribPointer(a_color,3,gl.UNSIGNED_BYTE,true,0,0)
			matrix=m4.projection(1000,1000,1000)//使用这个就不用在着色器内进行计算坐标了
			var aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
			var zNear = 1;
			var zFar = 2000;
			var fieldOfViewRadians = webglUtils.degreesToRadians(60);
			// matrix = m4.perspective(fieldOfViewRadians, 1, zNear, zFar);
			matrix=m4.translate(matrix,...translation)
			matrix=m4.translate(matrix,...centre)
			matrix=m4.rotate(matrix,webglUtils.degreesToRadians(rotate[0]),webglUtils.degreesToRadians(rotate[1]+r),webglUtils.degreesToRadians(rotate[2]))
			matrix=m4.scale(matrix,...scale)
			r++
			gl.uniformMatrix4fv(u_matrix,false,matrix)
			gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

			// Turn on culling. By default backfacing triangles
			// will be culled.
			gl.enable(gl.CULL_FACE);


			// Enable the depth buffer
			gl.enable(gl.DEPTH_TEST);
			gl.drawArrays(gl.TRIANGLES, 0, pos.length/3);
			requestAnimationFrame(draw)
		}
		draw()
		
	</script>
</body>
</html>
